home *** CD-ROM | disk | FTP | other *** search
- Name msggri
- ; File MSGIBM.ASM
- include mssdef.h
- ; Copyright (C) 1982,1991, Trustees of Columbia University in the
- ; City of New York. Permission is granted to any individual or
- ; institution to use, copy, or redistribute this software as long as
- ; it is not sold for profit and this copyright notice is retained.
- ; Tektronix emulator for use with MS Kermit/IBM.
- ; Edit history:
- ; 2 March 1991 version 3.10
- ; John Nyenhuis Purdue University School of Electrical Engineering
- ; West Lafayette IN 47907 (317)494-3524 nyenhuis@ee.ecn.purdue.edu
- ; November 1988
- ; Modify msgibm.asm to work with the GRiD Compass II
- ; Functionality is same as for IBM except for the more message in OUTSCRN
- ;
- ; Last edit 22 May 1988
- ; 1 July 1988 Version 2.31
- ; 22 May 1988 Add support for ESC [ Pn ; Pn m (ANSI) screen coloring.
- ; 22 March 1988 Add global byte Tekgraf which forces graphics board type
- ; 0=auto-sensing, 1=cga, 2=ega, 3=VGA, 4=Hercules, 5=ATT. Tekgraf stored
- ; here and set in file MSX by Set Term Graphics <board type>. Permit chars
- ; to overlap existing pixels. [jrd]
- ; 27 Feb 1988 Add tests for Toshiba T3100 (tnx for assist from Rob Preuss),
- ; for Olivetti M28/AT&T 6300+, and for DEC VAXmate II (tnx to Frank da Cruz)
- ; Add pointer based dispatch to character-font drawing routine. Add tests
- ; for stdin being a file rather than a device (keyboard). [jrd]
- ; 27 Jan 1988 Supress GIN and Status echos with Bypass byte. Bypass is reset
- ; by receipt of BEL, LF, CR, US, escape sequences, terminal reset.
- ; Bypass is set by receipt of ESC Control-E, ESC Control-X, ESC Control-Z.
- ; Make GIN mode crosshairs remember last GIN mode postion until the terminal
- ; is reset; make major steps smaller. Add ESC query-mark stands for DEL.
- ; Make Horizontal Tab (Control-I) a non-printing cursor control character
- ; to move right one column (with line wrap). Let real Hercules boards use
- ; both pages of memory (clones behave differently), tnx to Daniel Gruner.
- ; 1 Jan 1988 version 2.30
- ; 31 Dec 1987 change name from msvibm to msgibm for final release. [jrd]
- ; 29 Dec 1987 Add ESC [ ? 3 8 l as exit Tek mode command, from VT340's.[jrd]
- ; 26 Dec 1987 Add test to absorb echo of crosshairs report. [jrd]
- ; 22 Dec 1987 Revise parsing rules to make an escape sequence be a temporary
- ; interruption to the current command (except Clear Screen seq). [jrd]
- ; Add Control-C and Control-Break as non-reporting exits from GIN mode. [jrd]
- ; 21 Dec 1987 Add AT&T 6300, Olivetti M24 presence tests and run code. [jrd]
- ; 16 Dec 1987 Correct screen coloring for 64KB mono/med res color egas. [jrd]
- ; 4 Dec 1987 Add quirks for Environments, such as TopView, Windows. [jrd]
- ; 3 Dec 1987 Let 128KB EGA boards save screens. [jrd]
- ; 30 Nov 1987 Add relative plotting, thanks to help from Bob Parks. [jrd]
- ; 24 Nov 1987 Add dashed line patterns. [jrd]
- ; 21 Nov 1987 Add full color background. [jrd]
- ; 15 Nov 1987 Do screen clears manually because a Bios mode-set keeps
- ; interrupts off long enough to miss serial port characters. Make crosshairs
- ; smaller. [jrd]
- ; 8 Nov 1987 Modularize line drawing using Bresneham's algorithm, use pointers
- ; to action routines for different board types. Add screen save/restore.
- ; Do display board presence tests. Add FS as point plot introducer. Allow
- ; for virtual screens when operating under Environments (Windows, etc). [jrd]
- ; 1 Nov 1987 Heavy rewrite to integrate code into regular MS Kermit/IBM
- ; material. [jrd]
- ;==============================================================================
- ; Original version for TI Pro computers by
- ; 12-Dec-84 Joe Smith, CSM Computing Center, Golden CO 80401
- ; adapted to IBM PC June 1987 by Brian Holley,
- ; Faculty of Economics and Politics
- ; University of Cambridge, England
- ; Email: BJH6@UK.AC.CAM.PHX
- ; Upgraded and integrated into MS Kermit 2.30 by Joe Doupnik, Utah State Univ.
- ;
- ; Description of Tektronix commands
- ;
- ; ESCAPE-CONTROL-E (ENQ) requests a status report
- ; ESCAPE-FORMFEED erases the screen.
- ; ESCAPE-CONTROL-X turns on bypass mode (no screen characters).
- ; ESCAPE-CONTROL-Z turns on the crosshairs (not on 4006 or 4025)
- ; ESCAPE-? is replaced by DEL code, to assist line plots with 7 bit systems.
- ; ESCAPE [ Pn ; Pn m set screen colors. Pn = 30 + sum of colors for foregnd,
- ; 40 + sum of colors for background, Pn = 0 sets b/w, Pn = 1 for high
- ; intensity. Colors are red = 1, green = 2, blue = 4.
- ; ESCAPE [ ? 3 8 l exits Tek mode and returns to host text terminal type
- ; (VT102 if none defined yet). This is an extension from DEC VT340's.
- ; CONTROL-] (GS) turns on plot mode, the first move will be with beam off.
- ; CONTROL-^ (RS) turns on incremental plot mode. RS space means move pen up
- ; RS P means move pen down, following letters:A, E, D, F, B, J, H, I mean
- ; move right, right and up, up, left and up, left, left and down, down, and
- ; right and down, respectively. Ex: RS <space> J J J means move three Tek
- ; positions left and down with the pen up (invisibly).
- ; CONTROL-UNDERLINE (US) turns off plot mode, as does CR (for all but 4025).
- ; CONTROL-X switches from TEKTRONIX sub mode to NORMAL alpha mode but is
- ; ignored if we are emulating a full Tek terminal rather than a sub mode
- ; of DEC or Heath.
- ; FF erases screen.
- ; ESCAPE letter, where letter is accent grave (`), a-e sets the line drawing
- ; pattern until reset to solid lines (same as escape accent) by command or
- ; a terminal reset.
- ; where
- ; ENQ = Control E
- ; ESC = Control [ (left square bracket)
- ; FF = Control L
- ; FS = Control \ (backslash)
- ; GS = Control ] (right square bracket)
- ; RS = Control ^ (caret)
- ; US = Control _ (underscore)
- ;
- ; The plot commands are characters which specify the absolute position to move
- ; the beam. All moves except the one immediately after the GS character
- ; (Control-]) are with a visible trace.
- ;
- ; For 4010-like devices - The positions are from 0 to 1023 for both X and Y,
- ; although only 0 to 780 are visible for Y due to screen geometry. The screen
- ; is 10.23 by 7.80 inches, and coordinates are sent as 1 to 4 characters.
- ;
- ; For 4014-like devices - The positions are from 0 to 4096, but each movement
- ; is a multiple of 4 positions unless the high-resolution LSBXY are sent. This
- ; makes it compatible with the 4010 in that a full sized plot fills the screen.
- ;
- ; HIX,HIY = High-order 5 bits of position
- ; LOX,LOY = Middle-order 5 bits of position
- ; LSBXY = Low-order 2 bits of X + low-order 2 bits of Y (4014 mode)
- ;
- ; Hi Y Lo Y Hi X LSBXY Characters sent (Lo-X always sent)
- ; ---- ---- ---- ----- ----------------------------------
- ; Same Same Same Same Lo-X
- ; Same Same Same Diff LSB, Lo-Y, Lo-X 4014
- ; Same Same Diff Same Lo-Y, Hi-X, Lo-X
- ; Same Same Diff Diff LSB, Lo-Y, Hi-X, Lo-X 4014
- ; Same Diff Same Same Lo-Y, Lo-X
- ; Same Diff Same Diff LSB, Lo-Y, Lo-X 4014
- ; Same Diff Diff Same Lo-Y, Hi-X, Lo-X
- ; Same Diff Diff Diff LSB, Lo-Y, Hi-X, Lo-X 4014
- ; Diff Same Same Same Hi-Y, Lo-X
- ; Diff Same Same Diff Hi-Y, LSB, Lo-Y, Lo-X 4014
- ; Diff Same Diff Same Hi-Y, Lo-Y, Hi-X, Lo-X
- ; Diff Same Diff Diff Hi-Y, LSB, Lo-Y, Hi-X, Lo-X 4014
- ; Diff Diff Same Same Hi-Y, Lo-Y, Lo-X
- ; Diff Diff Same Diff Hi-Y, LSB, Lo-Y, Lo-X 4014
- ; Diff Diff Diff Same Hi-y, Lo-Y, Hi-X, Lo-X
- ; Diff Diff Diff Diff Hi-y, LSB, Lo-Y, Hi-X, Lo-X 4014
- ; Offset for byte: 20h 60h 60h 20h 40h
- ;
- ; Note that LO-Y must be sent if HI-X has changed so that the TEKTRONIX knows
- ; the HI-X byte (in the range of 20h-3fh) is HI-X and not HI-Y. LO-Y must
- ; also be sent if LSBXY has changed, so that the 4010 will ignore LSBXY and
- ; accept LO-Y. The LSBXY byte is 60h + MARGIN*10h + LSBY*4 + LSBX. (MARGIN=0)
- ;
- ;
- ;
- ; External variable tekflg and calls to tekini, tekemu, tekesc, tekcls:
- ; Byte TEKFLG is non-zero when the Tek emulator is active; it is set by the
- ; startup code in tekini and is maintained in this file. Internal variable
- ; inited remembers if we have a graphics screen saved, etc.
- ; TEKINI must be called when entering the emulator to establish the graphics
- ; screen mode and to calculate the screen dimensions.
- ; TEKRINT reinitialize complete emulator.
- ; TEKESC is called from say mszibm.asm to invoke Tek emulation when the
- ; external procedures have detected an Escape Control-L sequence. An implicit
- ; initialization is done if necessary.
- ; TEKEMU is the normal entry point to pass a received character to the emulator.
- ; It too will do an implicit initialization, if required.
- ; TEKCLS clears the graphics screen, but only if the emulator is active.
- ; The emulator remains active during Connect mode Help, Status, and other
- ; interrupts which do not change the terminal type.
-
- public tekemu,tekini,tekrint,tekend,tekgraf ; Terminal emulation
- public tekcls, tekesc, tekflg ; used by msz file
-
- ENQ equ 05h ; ^E ENQ for TEK enquiries
- CAN equ 18h ; ^X to return to ANSI mode
- ESCZ equ 1Ah ; SUB, ESC-^Z triggers crosshairs
- VT equ 0bh ; ^K go up one line
- FS equ 1ch ; ^\ for point plot mode
- GS equ 1Dh ; ^] draw line (1st move is invisible)
- RS equ 1Eh ; ^^ for incremental line plot mode
- US equ 1Fh ; ^_ (underscore) returns to text mode
- accent equ 60h ; accent grave
-
- txtmode equ 4 ; text mode for TEKTRONIX status
- maxtekx equ 1024 ; horizontal and
- maxteky equ 780 ; vertical resolution of TEK 4010
-
-
- uparr equ 72 ; DOS scan codes for arrow keys
- dnarr equ 80
- lftarr equ 75
- rgtarr equ 77
- homscn equ 71 ; DOS home screen scan code
- shuparr equ 73 ;code-arrow keys [jan]
- shdnarr equ 81
- shlftarr equ 212
- shrgtarr equ 213
-
- segcga equ 0040h ; grid display start [jan]
-
-
- hiy equ 1 ; codes for Tek graphics components
- loy equ 2
- hix equ 4
- lox equ 3
-
- data segment public 'data'
- extrn flags:byte, portval:word, rxtable:byte
- extrn bigscreen:byte, denyflg:word ; control tek auto entry/exit
-
-
- xmult dw 5 ; 320 = (5/16)*1024 small scrn [jan]
- xdiv dw 16 ; xmult/xdiv
- ymult dw 12 ; 240=(12/39)*780 small scrn [jan]
- ydiv dw 39 ; ymult/ydiv
- xmax dw 312 ; 320-8 x coord of right most chr [jan]
- ybot dw 239 ; 240 lines on small scrn [jan]
- linelen dw 40 ; offset increment between scan lines
- linebytes dw 40 ;40 bytes/line on small scn [jan]
-
-
-
- ttstate dw tektxt ; state machine control pointer
- prestate dw 0 ; previous state, across interruptions
- visible db 0 ; 0 to move, 1 to draw a line
- tek_hiy dw 0 ; Y coordinate in Tektronix mode
- tek_loy db 0
- tek_hix dw 0 ; X coordinate in Tektronix mode
- tek_lox db 0
- tek_lsb db 0 ; Low-order 2 bits of X + low Y
- ; (4014 mode)
- status db 0
- lastc db 0 ; last x/y coord fragment seen
- masktab db 80h,40h,20h,10h,8,4,2,1 ; quicker than calculations!
- ; dashed line patterns
- linetab dw 0ffffh ; ESC accent 11111111 11111111
- dw 0aaaah ; ESC a 10101010 10101010
- dw 0f0f0h ; ESC b 11110000 11110000
- dw 0fafah ; ESC c 11111010 11111010
- dw 0ffcch ; ESC d 11111111 11001100
- dw 0fc92h ; ESC e 11111100 10010010
-
- linepat dw 0ffffh ; active line pattern, from above
-
-
- ;End of init data
-
-
- IDSEQ dw tekem ; address of response to terminal
- CTLTAB dw 0 ; .. inquiry
- tekem db 'GRiD_TEK' ; .. and the response
- db escape,'/Z',0
- x_coord dw 0 ; Tek text char X coordinate
- y_coord dw 8 ; Tek text char Y coordinate
- xcross dw 0 ; cross hairs to start at centre
- ycross dw 0
- oldx dw 0 ; Tek coordinates of last point
- oldy dw 767 ; initially top left
- scalex dw 0 ; PC coord for scaled x value
- scaley dw 0 ; for scaled y value
- curmode db 0 ; screen mode before graphics
- tekgraf db 1 ; Tek graphics board selection (def=cga)[jan]
- ; local variables for LINE plotting routine
- cursor dw 0 ; saved text cursor
- inited db 0 ; non-zero if inited (retains page)
- tekflg db 0 ; Tek mode active flag
- yflags db 0 ; flags byte from msy
- flow dw 0 ; flow control word
- gpage db 0 ; display adapter graphics page
- gfcol db 15 ; graphics foreground colour
- gbcol db 0 ; graphics background color
- tfcol db 0 ; temp foreground color
- tbcol db 0 ; temp background color
- lastd db 0,0 ; worker for ESC [ Pn ; Pn m scanner
- ccode db 0 ;coloring
- moremsg db ' More >'
- mormsglen equ $-moremsg ; length of message
- putc dw gputc ; ptr to plot a character routine
- psetup dw psetupc ; ptr to plot setup routine
- pincy dw pincyc ; ptr to inc y routine
- plotptr dw pltcga ; ptr to dot plot routine
- gcplot dw gcgen ; ptr to char plot routine
- segscn dw 0040h ; actual screen segment to use[jan]
- ; ANSI Escape sequence to exit Tek mode
- tkoff db escape,'[?38l' ; Exit Tek mode escape sequence
- tkofflen equ $-tkoff ; length of sequence
- tkoffs db 6 dup (0) ; received chars in rcv'd sequence
- tkcnt dw 0 ; counter of matched char in tkoffs
- bypass db 0 ; GIN mode bypass condition (0=off)
- temp dw 0
-
- ; 8*8 font for Hercules and such, CGA, and EGA
- ; - allows 43 lines, and 80 (90 for Hercules) chars per line.
- ; all printing (?) characters from <space> to <del> - two characters per line
- ; 8 bits per scan line, given top line first, 8 scan lines.
- font db 0,0,0,0,0,0,0,0, 18h,18h,18h,18h,18h,0,18h,0
- db 6ch,6ch,6ch,0,0,0,0,0, 36h,36h,7fh,36h,7fh,36h,36h,0
- db 0ch,3fh,68h,3eh,0bh,7eh,18h,0, 60h,66h,0ch,18h,30h,66h,06h,0
- db 38h,6ch,6ch,38h,6dh,66h,3bh,0, 0ch,18h,30h,0,0,0,0,0
- db 0ch,18h,30h,30h,30h,18h,0ch,0, 30h,18h,0ch,0ch,0ch,18h,30h,0
- db 0,18h,7eh,3ch,7eh,18h,0,0, 0,18h,18h,7eh,18h,18h,0,0
- db 0,0,0,0,0,18h,18h,30h, 0,0,0,7eh,0,0,0,0
- db 0,0,0,0,0,18h,18h,0, 0,06h,0ch,18h,30h,60h,0,0
- db 3ch,66h,6eh,7eh,76h,66h,3ch,0, 18h,38h,18h,18h,18h,18h,7eh,0
- db 3ch,66h,06h,0ch,18h,30h,7eh,0, 3ch,66h,06h,1ch,06h,66h,3ch,0
- db 0ch,1ch,3ch,6ch,7eh,0ch,0ch,0, 7eh,60h,7ch,06h,06h,66h,3ch,0
- db 1ch,30h,60h,7ch,66h,66h,3ch,0, 7eh,06h,0ch,18h,30h,30h,30h,0
- db 3ch,66h,66h,3ch,66h,66h,3ch,0, 3ch,66h,66h,3eh,06h,0ch,38h,0
- db 0,0,18h,18h,0,18h,18h,0, 0,0,18h,18h,0,18h,18h,30h
- db 0ch,18h,30h,60h,30h,18h,0ch, 0,0,0,7eh,0,7eh,0,0,0
- db 30h,18h,0ch,06h,0ch,18h,30h, 0,3ch,66h,0ch,18h,18h,0,18h,0
- db 3ch,66h,6eh,6ah,6eh,60h,3ch, 0,3ch,66h,66h,7eh,66h,66h,66h,0
- db 7ch,66h,66h,7ch,66h,66h,7ch, 0,3ch,66h,60h,60h,60h,66h,3ch,0
- db 78h,6ch,66h,66h,66h,6ch,78h, 0,7eh,60h,60h,7ch,60h,60h,7eh,0
- db 7eh,60h,60h,7ch,60h,60h,60h, 0,3ch,66h,60h,6eh,66h,66h,3ch,0
- db 66h,66h,66h,7eh,66h,66h,66h, 0,7eh,18h,18h,18h,18h,18h,7eh,0
- db 3eh,0ch,0ch,0ch,0ch,6ch,38h, 0,66h,6ch,78h,70h,78h,6ch,66h,0
- db 60h,60h,60h,60h,60h,60h,7eh, 0,63h,77h,7fh,6bh,6bh,63h,63h,0
- db 66h,66h,76h,7eh,6eh,66h,66h, 0,3ch,66h,66h,66h,66h,66h,3ch,0
- db 7ch,66h,66h,7ch,60h,60h,60h, 0,3ch,66h,66h,66h,6ah,6ch,36h,0
- db 7ch,66h,66h,7ch,6ch,66h,66h, 0,3ch,66h,60h,3ch,06h,66h,3ch,0
- db 7eh,18h,18h,18h,18h,18h,18h, 0,66h,66h,66h,66h,66h,66h,3ch,0
- db 66h,66h,66h,66h,66h,3ch,18h, 0,63h,63h,6bh,6bh,7fh,77h,63h,0
- db 66h,66h,3ch,18h,3ch,66h,66h, 0,66h,66h,66h,3ch,18h,18h,18h,0
- db 7eh,06h,0ch,18h,30h,60h,7eh, 0,7ch,60h,60h,60h,60h,60h,7ch,0
- db 0,60h,30h,18h,0ch,06h,0,0, 3eh,06h,06h,06h,06h,06h,3eh,0
- db 18h,3ch,66h,42h,0,0,0,0, 0,0,0,0,0,0,0,0ffh
- db 30h,18h,0ch,0,0,0,0,0, 0,0,3ch,06h,3eh,66h,3eh,0
- db 60h,60h,7ch,66h,66h,66h,7ch,0, 0,0,3ch,66h,60h,66h,3ch,0
- db 06h,06h,3eh,66h,66h,66h,3eh,0, 0,0,3ch,66h,7eh,60h,3ch,0
- db 0eh,18h,18h,3ch,18h,18h,18h,0, 0,0,3eh,66h,66h,3eh,06h,3ch
- db 60h,60h,7ch,66h,66h,66h,66h,0, 18h,0,38h,18h,18h,18h,3ch,0
- db 18h,0,38h,18h,18h,18h,18h,70h, 60h,60h,66h,6ch,78h,6ch,66h,0
- db 38h,18h,18h,18h,18h,18h,3ch,0, 0,0,76h,7fh,6bh,6bh,63h,0
- db 0,0,7ch,66h,66h,66h,66h,0, 0,0,3ch,66h,66h,66h,3ch,0
- db 0,0,7ch,66h,66h,7ch,60h,60h,0, 0,3eh,66h,66h,3eh,06h,07h
- db 0,0,6ch,76h,60h,60h,60h,0, 0,0,3eh,60h,3ch,06h,7ch,0
- db 30h,30h,7ch,30h,30h,30h,1ch,0, 0,0,66h,66h,66h,66h,3eh,0
- db 0,0,66h,66h,66h,3ch,18h,0, 0,0,63h,6bh,6bh,7fh,36h,0
- db 0,0,66h,3ch,18h,3ch,66h,0, 0,0,66h,66h,66h,3eh,06h,3ch
- db 0,0,7eh,0ch,18h,30h,7eh,0, 0ch,18h,18h,70h,18h,18h,0ch,0
- db 18h,18h,18h,0,18h,18h,18h,0, 30h,18h,18h,0eh,18h,18h,30h,0
- db 31h,6bh,46h,0,0,0,0,0, 8 dup (0ffh)
- data ends
-
- code segment public 'code'
- extrn outchr:near, beep:near, cmblnk:near
- extrn clrmod:near, cptchr:near
- extrn clrbuf:near, iseof:near, getflgs:near
- extrn termtog:near ; toggle terminal type [jan]
- assume cs:code, ds:data, es:nothing
-
- ; Initialise TEK mode by setting high resolution screen, etc
-
- tekini PROC NEAR
- push ax
- push bx
- push cx
- push dx
- push si
- push di
- push es
- cmp bigscreen,0 ;1means big
- je tekin1 ;eq means use defaults
- mov xmult,1 ;512=(1/2) x 1024 big scrn [jan]
- mov xdiv,2 ;512 columns on big screen
- mov ymult,64 ;256=(64/195)*780
- mov ydiv,195 ;256 rows on big screen
- mov xmax,504 ;5-2-8 x coord of right most chr
- mov ybot,255 ;256 lines on big screen
- mov linelen,64 ;64 bytes per line
- mov linebytes,64
- jmp tekin2
- tekin1: mov xmult,10 ;small screen stuff
- mov xdiv,32 ;small is 320 x 240
- mov ymult,12
- mov ydiv,39
- mov xmax,312
- mov ybot,239
- mov linelen,40
- mov linebytes,40
-
-
- tekin2: mov tekflg,1 ; starting Tek sub mode
- ; cmp inited,0 ; inited yet?
- ; jne tekin19 ; ne = yes, restore screen
- mov ttstate,offset tektxt ; do displayable text
- mov prestate,offset tektxt ; set a previous state of text
- mov inited,1 ; say we have initialized
- ; call tekcls ; clear screen
- ; jmp short tekin20
- ;tekin19:call tekrest ; restore old graphics screen
- tekin21:clc ; clear carry for success
- tekin23:pop es
- pop di
- pop si
- pop dx
- pop cx
- pop bx
- pop ax
- ret
- tekini ENDP
-
- TEKRINT proc near ; Tek reinitialization entry point
- mov inited,0 ; do complete reinitialization
- jmp tekini
- TEKRINT endp
-
-
- ;Terminal emulation. Enter with received character in AL.
-
- TEKEMU PROC NEAR ; main emulator
- cmp tekflg,0 ; Tek mode active yet? (msz call)
- jne tektt1 ; ne = yes
- call tekini ; init now
- mov ttstate,offset tektxt ; initial state
- mov prestate,offset tektxt ; set a previous state of text
- jnc tektt1 ; nc = succeeded
- ret ; else failed to init, just return
- tektt1: and al,7fh ; force Tek chars to be 7 bits
- cmp al,0 ; NUL char?
- je tekign ; e = yes, ignore it before logging
- push ax
- call getflgs ; get msy yflags into al
- mov yflags,al
- test al,capt ; capturing output?
- pop ax
- jz tektt4 ; z = no, forget this part
- push ax ; save char
- call cptchr ; give it captured character
- pop ax ; restore character and keep going
- tektt4: test yflags,trnctl ; debug? if so use tty mode
- jz tektt5 ; z = no
- cmp al,DEL ; DEL char?
- jne tektt4a ; ne = no
- mov al,5eh ; make DEL a caret query mark
- call outscrn
- mov al,3fh ; the query mark
- call outscrn
- jmp short tekign
- tektt4a:cmp al,' ' ; control char?
- jae tektt4b ; ne = no
- push ax
- mov al,5eh ; caret
- call outscrn
- pop ax
- add al,'A'-1 ; make char printable
- tektt4b:call outscrn
-
- tekign: ret ; Ignore this character
-
- tektt5: call tkscan ; scan for "ESC [ ? 3 8 l" exit code
- tektt5a:cmp al,0 ; null char response?
- je tekign ; e = yes, ignore the character
- cmp al,' ' ; control code?
- jb tektt6 ; b = yes, decode
- jmp ttstate ; no, do current state
- ; Control characters:
- tektt6: cmp al,GS ; Line plot command?
- jne tektt7 ; ne = no
- mov visible,0 ; Next move is invisible
- and status,not txtmode ; set status report byte
- mov ttstate,offset tekline ; expect coordinates next
- jmp tektt12
- tektt7: cmp al,RS ; Incremental dot command?
- jne tektt8 ; ne = no
- and status,not txtmode ; set status report
- mov ttstate,offset tekrlin ; expect pen command next
- jmp tektt12
- tektt8: cmp al,FS ; Point plot command?
- jne tektt9 ; ne = no
- mov visible,0 ; next move is invisible
- and status,not txtmode ; set status report byte
- mov ttstate,offset tekpnt
- jmp tektt12
- tektt9: cmp al,US ; assert text mode? [bjh]
- jne tektt10 ; ne = no
- or status,txtmode ; set status report byte
- mov ttstate,offset tektxt ; Go to TEKTXT next time
- mov bypass,0 ; reset bypass condition
- jmp tektt12
- tektt10:cmp al,ESCAPE ; Escape?
- jne tektt11 ; ne = no
- or status,txtmode ; set status report byte
- cmp ttstate,offset tekesc ; already in escape state?
- je tektt14 ; e = yes, nest no further
- push ttstate ; current state
- pop prestate ; save here as previous state
- mov ttstate,offset tekesc ; next state parses escapes
- ret
- tektt11:cmp al,CAN ; Control X? (exits Tek sub mode)
- jne tektt13 ; ne = no, stay in current state
- cmp ttstate,offset tekesc ; ESC Control-X?
- je tektt13 ; yes, parse it in tekesc code
- mov ttstate,offset tektxt ; back to text mode
- ; test flags.vtflg,tttek ; main Tek emulator?
- test denyflg,tekxflg ;disable auto exit/entry [jan]
- jnz tektt12 ; nz = yes, ignore the ^X
- call tekend ; else exit sub mode
- mov tekflg,0 ; clear Tek sub mode flag
- tektt12:mov prestate,offset tektxt ; make previous state text
- tektt14:ret
- tektt13:jmp ttstate ; let someone else worry about this
- TEKEMU ENDP
-
- ; End TEK emulation, recover previous screen
- TEKEND PROC NEAR
- cmp tekflg,0 ; Tek sub mode active?
- jne teknd0 ; ne = yes
- ret ; else return as is.
- teknd0: call termtog ;toggle terminal
- ret
- TEKEND ENDP
-
- ; State machine active while Tek is active. Senses ESC [ ? 3 8 l to exit
- ; Tek mode and return to either non-sub mode terminal or to a VT102.
- ; Plays back unmatched escape sequences. Enter with character in al.
-
- tkscan proc near
- and al,7fh ; strip high bit
- cmp al,byte ptr tkoff ; start of Tek Off sequence?
- jne tkscn1 ; ne = no
- call tkscn4 ; playback previously matched chars
- mov tkcnt,1 ; count matched chars (one now)
- mov tkoffs,al ; save full character, with high bit
- mov al,0 ; our temporary response
- jmp short tkscnx ; and exit
-
- tkscn1: push bx ; check for char in Tek Off sequence
- mov bx,tkcnt ; number of chars matched in Tek Off
- mov tkoffs[bx],al ; save this char
- cmp al,byte ptr tkoff[bx] ; match expected char in sequence?
- pop bx
- jne tkscn3 ; ne = no, play back partial match
- inc tkcnt ; count new match
- mov al,0 ; our temporary response
- cmp tkcnt,tkofflen ; matched all char in sequence?
- jne tkscnx ; ne = not yet, wait for more
- mov tkcnt,0 ; clear counter
- cmp flags.vtflg,tttek ;full terminal now?
- jne tkscn2 ; ne = no, a submode
- ; call termtog ; toggle terminal type[jan]
- tkscn2: mov al,CAN ; simulate arrival of Control-X
- jmp short tkscnx ; all done
-
- tkscn3: call tkscn4 ; playback previously matched chars
- mov tkcnt,0 ; reset to no match and exit
- tkscnx: ret ; common exit
-
- ; local worker procedure
- tkscn4: push ax ; save break char (in al)
- push cx ; playback partial sequence to screen
- mov cx,tkcnt ; number of chars matched before break
- jcxz tkscn4b ; z = none
- push si
- mov si,offset tkoffs ; string to be played back
- tkscn4a:cld
- lodsb ; get a char into al
- push cx
- push si ; save these around tektt5a work
- call tektt5a ; use it
- pop si
- pop cx
- loop tkscn4a ; do all that came in previously
- pop si
- tkscn4b:pop cx
- pop ax ; recover break char
- ret
- tkscan endp
-
-
- TEKTXT proc near ; Dispatch on text characters
-
- cmp al,DEL ; RUBOUT?
- jne tektx1 ; ne = no
- mov al,bs ; make BS
- jmp short tektx7
- tektx1: cmp al,CR ; carriage return (^M)?
- je tektx9 ; e = yes
- tektx2: cmp al,LF ; line feed (^J)?
- je tektx9 ; e = yes
- tektx3: cmp al,FF ; form feed (^L)?
- jne tektx4 ; ne = no
- call tekcls ; clear the screen
- jmp short tektx8
- tektx4: cmp al,VT ; vertical tab (^K)?
- je tektx7
- cmp al,bell ; bell (^G)?
- jne tektx5 ; ne = no
- call beep
- mov bypass,0 ; clear GIN mode bypass condition
- jmp short tektx8
- tektx5: cmp al,tab ; horizontal tab (^I)?
- je tektx7 ; e = yes
- tektx6: cmp al,BS ; backspace (^H)?
- je tektx7 ; e = yes
- cmp al,' ' ; control char?
- jb tektx8 ; b = yes, ignore it
- tektx7: cmp bypass,0 ; bypass mode off?
- jne tektx8 ; ne = no, it's on so skip display
- call OUTSCRN ;output character to screen
-
- tektx8: ret
- tektx9: mov bypass,0 ; clear GIN mode bypass condition
- jmp short tektx7
- TEKTXT endp
-
- ; Process escape sequences. Callable from msz terminal emulator.
- ; Enter with received character in AL. Escape sequences are generally
- ; treated as interruptions to the current plotting/text command. Screen
- ; clearing is the exception by causing a general emulator reset.
- TEKESC PROC NEAR
- mov bypass,0 ; clear GIN mode bypass condition
- mov ttstate,offset tekesc ; in case get here from msz file
- cmp tekflg,0 ; Tek mode active yet? (msz call)
- jne tekesc1 ; ne = yes
- call tekini ; init now
- mov prestate,offset tektxt ; set a previous state of text
- jnc tekesc1 ; nc = succeeded
- ret ; else failed to init, just return
-
- tekesc1:cmp al,'Z' ; ESC-Z Identify?
- jne tekesc2 ; ne = no
- ; call SENDID ; Send terminal identification
- jmp tekescx
-
- tekesc2:cmp al,FF ; ESC-FF Clear screen?
- jne tekesc3 ; ne = no
- call tekcls ; Clear screen
- mov prestate,offset tektxt ; make previous state text mode
- jmp tekescx ; Return to text mode after ESC-FF
-
- tekesc3:cmp al,ESCZ ; ESC-^Z Enter GIN mode?
- jne tekesc4 ; ne = no
- mov bypass,1
- call CROSHAIR ; Activate the cross-hairs
- jmp tekescx
- tekesc3a:call beep ; tell the user we are unhappy
- jmp tekescx ; and ignore the command
-
- tekesc4:cmp al,ENQ ; ESC-^E Enquiry for cursor position?
- jne tekesc5 ; ne = no
- mov bypass,1 ; set bypass mode
- call SENDSTAT ; send status
- jmp tekescx
-
- tekesc5:cmp al,CAN ; ESC Control-X?
- jne tekesc6 ; ne = no
- mov bypass,1 ; set bypass condition
- jmp tekescx
-
- tekesc6:cmp al,3fh ; query mark? (ESC ? means DEL)
- jne tekesc7 ; ne = no
- mov al,DEL ; replace with DEL code
- jmp tekescx ; and process it as if received.
-
- tekesc7:cmp al,accent ; accent grave, line pattern series?
- jb tekesc8 ; b = no
- cmp al,65h ; lowercase e?
- ja tekescx ; a = beyond line pattern series
- push bx
- mov bl,al
- sub bl,accent ; remove bias
- and bl,7 ; eight patterns, roll over excess
- mov bh,0
- shl bx,1 ; make this a word index
- mov bx,linetab[bx] ; get line pattern word
- mov linepat,bx ; save in active word
- pop bx ; return to previous mode
-
- tekesc8:cmp al,5bh ; right square bracket?
- jne tekescx ; ne = no
- ; jmp tekcol ; no color on GRiD [jan]
-
- tekescx:push ax
- mov ax,prestate ; get previous state
- mov ttstate,ax ; restore it
- or ax,ax ; test for none
- pop ax
- jz go2text ; z = none, use text mode
- clc
- ret ; resume previous state
-
- go2text:mov ttstate,offset tektxt ; Go to TEKTXT next time
- mov lastc,0 ; clear last drawing coordinate flag
- or status,txtmode ; set text mode in status byte
- clc
- ret
- TEKESC ENDP
-
-
-
- TEKLINE proc near ; GS line drawing
- call tekxyc ; parse coordinates from input bytes
- jnc teklin1 ; nc = not done yet
- mov cl,visible ; get moveto or drawto variable
- call tekdraw ; move that point
- mov visible,1 ; say next time we draw
- teklin1:ret
- TEKLINE endp
-
- TEKPNT proc near ; FS plot single point
- call tekxyc ; parse coordinates
- jnc tekpnt1 ; nc = not done yet
- mov cl,0 ; do not draw
- call tekdraw ; move to the point
- mov ax,si ; copy starting point to end point
- mov bx,di ; ax,bx,si,di are in PC coordinates
- mov cl,1 ; make plot visible
- call line ; draw the dot
- mov visible,0 ; return to invisibility
- tekpnt1:ret
- TEKPNT endp
-
- ; Decode graphics x,y components. Returns carry set to say have all
- ; components for a line, else carry clear. Understands 4014 lsb extensions.
- ; Permits embedded escape sequences.
- TEKXYC proc near
- cmp al,CR ; Exit drawing on CR,LF,RS,US,FS,CAN
- je tekghx ; e = yes, a cr
- cmp al,LF ; these terminate line drawing cmds
- je tekghx
- cmp al,FS ; <FS>
- je tekghx
- cmp al,RS ; <RS>
- je tekghx
- cmp al,US ; <US>
- je tekghx
- cmp al,CAN ; and <CAN>
- je tekghx ; BUT ignore other control chars
- cmp al,20h ; Control char?
- jb tekgh0 ; b = yes, ignore it
- cmp al,40h
- jb tekgh2 ; 20-3F are HIX or HIY
- cmp al,60h ; 40-5F are LOX (causes beam movement)
- jb tekgh4 ; 60-7F are LOY
- ; Extract low-order 5 bits of Y coord
- mov ah,tek_loy ; Copy previous LOY to MSB (4014)
- mov tek_lsb,ah
- and al,1Fh ; LOY is 5 bits
- mov tek_loy,al
- cmp lastc,loy ; 2nd LOY in a row?
- je tekgh1 ; Yes, then LSB is valid
- mov tek_lsb,0 ; 1st one, clear LSB
- tekgh1: mov lastc,loy ; LOY seen, expect HIX (instead of HIY)
- tekgh0: clc ; c clear = not completed yet
- ret
- tekghx: jmp go2text
-
- ; Extract high-order 5 bits (X or Y, depending on lastc)
- tekgh2: and ax,1Fh ; Just 5 bits
- mov cl,5
- shl ax,cl ; Shift over 5 bits
- cmp lastc,loy ; was last coordinate a low-y?
- je tekgh3 ; e = yes, parse hix
- mov tek_hiy,ax ; this byte has HIY
- mov lastc,hiy
- clc
- ret
- tekgh3: mov tek_hix,ax ; This byte has HIX
- mov lastc,hix
- clc
- ret
- tekgh4: and al,1Fh ; Just 5 bits
- mov tek_lox,al
- mov lastc,lox
- mov ax,tek_hix ; Combine HIX*32
- or al,tek_lox ; with LOX
- mov bx,tek_hiy ; Same for Y
- or bl,tek_loy
- stc ; set c to say completed operation
- ret
- TEKXYC endp
-
- TEKRLIN proc near ; RS relative line drawing
- cmp al,' ' ; Pen up command?
- jne tekrli1 ; ne = no, try pen down
- mov visible,0 ; do invisible movements
- jmp short tekrli2 ; do the command
- tekrli1:cmp al,'P' ; pen down command?
- jne tekrli3 ; ne = no, return to text mode
- mov visible,1 ; set visible moves
-
- tekrli2:mov ax,x_coord ; PC x coordinate of pen
- mov bx,y_coord ; y coordinate
- call pctotek ; get current pen position in Tek coor
- mov cl,0 ; invisible, moveto
- call tekdraw ; move that point, set oldx and oldy
- mov ttstate,offset tekinc ; next get incremental movement cmds
- ret
-
- tekrli3:mov visible,0 ; bad char, reset visibility
- push prestate
- pop ttstate ; restore previous state
- jmp tektt5 ; deal with the break char
- TEKRLIN endp
- ; interpret RS inc plot command byte
- TEKINC proc near ; get movement character and do cmd
- cmp al,'A' ; move right?
- jne tekinc1 ; ne = no
- inc oldx ; adjust beam position
- jmp short tekinc9
- tekinc1:cmp al,'E' ; move right and up?
- jne tekinc2 ; ne = no
- inc oldx
- inc oldy
- jmp short tekinc9
- tekinc2:cmp al,'D' ; move up?
- jne tekinc3 ; ne = no
- inc oldy
- jmp short tekinc9
- tekinc3:cmp al,'F' ; move left and up?
- jne tekinc4 ; ne = no
- dec oldx
- inc oldy
- jmp short tekinc9
- tekinc4:cmp al,'B' ; move left?
- jne tekinc5 ; ne = no
- dec oldx
- jmp short tekinc9
- tekinc5:cmp al,'J' ; move left and down?
- jne tekinc6 ; ne = no
- dec oldx
- dec oldy
- jmp short tekinc9
- tekinc6:cmp al,'H' ; move down?
- jne tekinc7 ; ne = no
- dec oldy
- jmp short tekinc9
- tekinc7:cmp al,'I' ; move right and down?
- jne tekincb ; ne = no, bad command
- inc oldx
- dec oldy
- tekinc9:cmp oldx,0 ; too far left?
- jge tekinc10 ; ge = no
- mov oldx,0 ; else stop at the left margin
- tekinc10:cmp oldx,maxtekx-1 ; too far left?
- jle tekinc11 ; le = no
- mov oldx,maxtekx-1 ; else stop that the left margin
- tekinc11:cmp oldy,maxteky-1 ; above the top?
- jle tekinc12 ; le = no
- mov oldy,maxteky-1 ; else stop at the top
- tekinc12:cmp oldy,0 ; below the bottom?
- jge tekinc13 ; ge = no
- mov oldy,0 ; else stop at the bottom
- tekinc13:mov ax,oldx ; ax is vector x end point
- mov bx,oldy ; bx is vector y end point
- mov cl,visible
- call tekdraw ; move/draw to that point
- ret
- tekincb:push prestate ; bad character, exit inc plot mode
- pop ttstate ; new state is previous state
- mov visible,0
- jmp tektt5 ; reparse the bad char
- TEKINC endp
-
-
- ; Routine to trigger the crosshairs, wait for a key to be struck, and send
- ; the typed char (if printable ascii) plus four Tek encoded x,y position
- ; coordinates and then a carriage return.
- ; ax, cx, xcross, ycross operate in PC coordinates.
-
- CROSHAIR PROC NEAR
- push linepat ; save line drawing pattern
- mov linepat,0ffffh ; reset line type to solid
-
- mov ax,xmax ; right margin minus 7 dots
- add ax,7
- mov temp,ax ; right margin dot
- crosha1:call crosdraw ; draw the cross-hairs
- call iseof ; is stdin at EOF?
- jc crosha2 ; c = yes, exit this mode now
- mov ah,coninq ; DOS, quiet read char
- int dos
- push ax ; save char for later
- call crosdraw ; erase cross hairs
- pop ax
- or al,al ; ascii or scan code returned
- jnz arrow5 ; nz = ascii char returned
-
- call iseof ; is stdin at EOF?
- jc crosha2 ; c = yes, exit this mode now
- mov ah,coninq ; read scan code
- int dos
- cmp al,0 ; Control-Break?
- jne crosha3 ; ne = no, something else
- crosha2:pop linepat ; restore line pattern
- ret ; exit crosshairs mode
-
- crosha3:cmp al,homscn ; is it 'home'?
- jne arrow1 ; ne = no, try other keys
- mov ax,temp ; right margin
- shr ax,1 ; central position
- mov xcross,ax ; save PC coord for crosshair
- mov ax,ybot ; last scan line
- shr ax,1
- mov ycross,ax ; this is the center of the screen
- jmp crosha1 ; home the crosshairs
-
- arrow1: cmp al,lftarr ; left arrow?
- jne arrow2 ; ne = no
- mov cx,-1 ; left shift
- jmp short xkeys
- arrow2: cmp al,rgtarr ; right arrow?
- jne arrow3 ; ne = no
- mov cx,1 ; right shift
- jmp short xkeys
- arrow3: cmp al,uparr ; up arrow?
- jne arrow4 ; ne = no
- mov cx,-1 ; up shift
- jmp short vertkey
- arrow4: cmp al,dnarr ; down arrow?
- jne arrow7 ; ne = no, ignore it
- mov cx,1 ; down shift
- jmp short vertkey
-
- arrow7: cmp al,shuparr ; shifted up arrow?
- jne arrow8 ; ne = no
- mov cx,-10 ; big up shift
- jmp short vertkey
- arrow8: cmp al,shdnarr ; shifted down arrow?
- jne badkey ; ne = no, send this key as is
- mov cx,10 ; big down shift
- jmp short vertkey
-
-
- badkey: call beep ; tell user we don't understand
- jmp crosha1 ; keep going
-
- ; Shifted keys yield ascii keycodes
- arrow5: cmp al,'C' and 1fh ; Control-C?
- je crosha2 ; e = yes, exit crosshairs mode now
- cmp al,shlftarr ; shifted left arrow?
- jne arrow6 ; ne = no
- mov cx,-10 ; big left shift
- jmp short xkeys
- arrow6: cmp al,shrgtarr ; shifted right arrow?
- jne charkey ; ne = no
- mov cx,10 ; big right shift
- jmp short xkeys
-
- xkeys: add cx,xcross ; add increment
- jns noxc ; gone too far negative?
- mov cx,0 ; yes - then make it 0
- noxc: cmp cx,temp ; too far right?
- jb xdraw9 ; b = no
- mov cx,temp ; yes - then make it the right
- xdraw9: mov xcross,cx ; new x value for cross hairs
- jmp crosha1 ; and redraw
-
- vertkey:add cx,ycross ; adjust cx
- jns noyc ; gone negative?
- mov cx,0 ; yes then make 0
- noyc: cmp cx,ybot ; too high?
- jb yok
- mov cx,ybot ; make it maximum
- yok: mov ycross,cx ; save new y crosshair
- jmp crosha1 ; and redraw
-
- charkey:call clrbuf ; purge received data to date
- call outmodem ; send the break character
- mov ax,xcross ; set beam to xcross,ycross
- mov bx,ycross ; must convert to Tek coordinates
- call pctotek ; scale from PC screen coord to Tek
- push ax ; save around drawing
- push bx
- mov cx,0 ; just a move
- call tekdraw ; moveto ax,bx in Tek coord
- pop bx ; recover Tek y
- pop ax ; recover Tek x
- call sendpos ; send position report to host
- pop linepat ; recover current line drawing pattern
- mov ttstate,offset tektxt ; Go to TEKTXT next time
- mov lastc,0 ; clear last drawing coordinate flag
- or status,txtmode ; set text mode in status byte
- ret
- CROSHAIR ENDP
-
- ; CROSDRAW draws cross-hairs by XORing cross with picture.
- ; xcross and ycross are in PC coordinates.
- CROSDRAW PROC NEAR
- mov si,xcross ; move to (xcross, ycross-10)
- mov di,ycross
- sub di,10 ; half the size of the cross
- jns crosd1 ; no sign bit means ok
- mov di,0 ; else limit to start of screen
- crosd1: mov ax,si ; next, draw to (xcross, ycross+10)
- mov bx,ycross ; make bottom stroke
- add bx,10
- cmp bx,ybot ; too large?
- jbe crosd2 ; be = no
- mov bx,ybot ; vertical line to (xcross,ybot)
- crosd2: mov cx,0ffh ; invert pixels
- call line ; and draw vertical
- sub si,12 ; move to (xcross-12, ycross)
- jns crosd3 ; no sign means ok
- mov si,0 ; else limit to start of line
- crosd3: mov di,ycross
- mov bx,di
- mov ax,xcross ; draw to (xcross+12, ycross)
- add ax,12
- cmp ax,temp ; temp is right margin, too large?
- jbe crosd4 ; be = no, ok
- mov ax,temp ; max x value
- crosd4: mov cx,0ffh ; set XOR code
- call line ; draw to (xcross+12, ycross)
- ret
- CROSDRAW ENDP
-
- ; SENDPOS sends position of cross-hairs to the host.
- ; ax has Tek X and bx has Tek Y coord of center of crosshair
- SENDPOS PROC NEAR
- push bx ; preserve register
- call sendxy ; send x coord
- pop ax
- call sendxy ; send y coord
- mov al,cr ; follow up with cr
- call outmodem
- ret
- SENDPOS ENDP
-
- ; SENDXY sends value of ax as Tek encoded bytes
- ; ax is in Tek coordinates
- SENDXY PROC NEAR
- shl ax,1
- shl ax,1 ; move all but lower 5 bits to ah
- shl ax,1
- shr al,1
- shr al,1 ; move low five bits to low 5 bits
- shr al,1
- or ah,20h ; make it a printing char as per TEK
- xchg al,ah ; send high 5 bits first
- call outmodem
- xchg al,ah ; then low five bits
- or al,20h
- call outmodem
- xchg ah,al ; al is first sent byte
- ret
- SENDXY ENDP
-
-
- SENDID PROC NEAR ; Pretend VT100 with graphics option
- mov bx,IDSEQ ; Get addr of string
- sndid1: mov al,[bx] ; Get char from sequence
- cmp al,0 ; End of sequence?
- jz sndid0 ; Yes, return
- call OUTMODEM ; Send it out the port
- inc bx
- jmp sndid1
- sndid0: ret
- SENDID ENDP
-
- ; SENDSTAT - send status and cursor position to host
-
- SENDSTAT PROC NEAR
- mov al,STATUS ; get tek status
- or al,20h ; make it printable
- call OUTMODEM ; and send it
- mov ax,oldx ; now send x coordinate (oldx is Tek)
- call SENDXY
- mov ax,oldy ; and y coordinate (oldy is Tek coord)
- call SENDXY
- mov al,cr ; end with a cr
- call OUTMODEM
- ret
- SENDSTAT ENDP
-
- ; routine to send al to the modem port
-
- OUTMODEM PROC NEAR
- push ax
- mov ah,al
- call outchr ; outchr reads from ah
- nop ; ignore errors
- nop
- nop
- pop ax
- ret
- OUTMODEM ENDP
-
- ; Convert X and Y from PC coordinates to Tek coordinates. AX = X, BX = Y
- ; for both input and output.
- pctotek proc near
- mul xdiv ; scale from PC screen coord to Tek
- div xmult
- xchg bx,ax ; save Tek x coord in bx
- neg ax ; y axis. Turn upside down for Tek
- add ax,ybot
- mul ydiv ; scale y from PC screen coord to Tek
- div ymult
- xchg ax,bx ; ax has X, bx has Y in Tek coords
- ret
- pctotek endp
-
- ; Routine to output character in AL to the screen.
-
- OUTSCRN PROC NEAR ; Output one character to the screen
- cmp bypass,0 ; GIN mode bypass off?
- je outscp ; e = yes
- ret ; else ignore characters
- outscp: ; Set Translation Input filter
- cmp rxtable+256,0 ; translation turned off?
- je outsct ; e = yes, no translation
- push bx
- mov bx,offset rxtable ; address of translate table
- xlatb ; new char is in al
- and al,7fh ; retain only lower seven bits
- pop bx
- outsct: mov ccode,1 ; normal text [jan]
- mov si,ybot ; get last scan line
- inc si ; number of scan lines
- sub si,y_coord ; minus where char bottom needs to go
- jnc outscc ; nc = enough space for char
- ; took out more stuff [jan]
- mov y_coord,0 ; back to top of screen [jan]
-
- outscc: push ax
- mov ax,xmax
- cmp x_coord,ax ; beyond right margin?
- jbe outsc3 ; be = no
- mov al,cr ; else simulate cr/lf
- call putc ; before displaying current char
- mov al,lf
- call putc
- outsc3: pop ax
- call putc ; routine to draw characters
- ret
- OUTSCRN ENDP
-
-
-
-
- ; TEKCLS routine to clear the screen.
- ; Entry point tekcls1 clears screen without resetting current point.
- TEKCLS PROC NEAR
- cmp tekflg,0 ; Tek sub mode active yet?
- jne tekcls0 ; ne = yes
- ret ; else ignore this call
- tekcls0:mov x_coord,0 ; starting text coordinates
- mov y_coord,8
- mov oldx,0 ; assumed cursor starting location
- mov oldy,maxteky ; top right corner (Tek coord)
- mov scalex,0 ; clear last plotted point (PC coord)
- mov scaley,0
- mov lastc,0 ; last parsed x,y coordinate
- mov visible,0 ; make lines invisible
- mov linepat,0ffffh ; reset line pattern to solid
- mov ccode,1 ; reset to ordinary writing
- mov bypass,0 ; clear bypass condition
- mov ttstate,offset tektxt ; do displayable text
- push ax
- mov ax,xmax ; right margin minus 7 dots
- add ax,7 ; right most dot
- shr ax,1 ; central position
- mov xcross,ax ; save PC coord for crosshair
- mov ax,ybot ; last scan line
- shr ax,1
- mov ycross,ax ; this is the center of the screen
- pop ax
-
- tekcls1:push ax ; save registers
- push cx
- call cmblnk ; clear the screen
- tekcls7:mov si,0 ; starting x (in case screen is
- mov di,0 ; starting y cleared by user)
- pop cx
- pop ax
- ret
- TEKCLS ENDP
-
-
-
- ; Routine to draw a line on the screen, using TEKTRONIX coordinates.
- ; X coordinate in AX, 0=left edge of screen, 1023=right edge of screen.
- ; Y coordinate in BX, 0=bottom of screen, 779=top of screen.
- ; CL=0 - invisible move, CL=1 - draw a line, CL=0FFh - invert pixels on line
-
- TEKDRAW PROC NEAR
- mov si,scalex ; get old x already scaled
- mov di,scaley ; get old y already scaled
- call scale ; scale new end point to PC coords
- cmp cl,0 ; invisible drawing?
- je moveto ; z = just move, skip draw part
- call LINE ; draw the line
- moveto: mov x_coord,ax ; update text coordinates to match
- mov y_coord,bx ; last drawn point
- ret
- TEKDRAW ENDP
-
- ; Scale TEKTRONIX coordinates to the currently defined screen coordinates
- ; AX holds X axis, BX holds Y axis. Both are changed from Tektronix coord
- ; to PC coordinates by this procedure.
- SCALE PROC NEAR
- push dx
- push si
- mov oldx,ax ; save current Tek x for next draw
- mov oldy,bx ; save current Tek y for next draw
- mul xmult ; scale x-coord
- mov si,xdiv ; get the divisor
- shr si,1 ; halve it
- add ax,si ; add in - to round to nearest integer
- adc dx,0
- div xdiv
- cmp oldx,maxtekx-1 ;at right of screen? [jan]
- jne scale2 ;ne means not at edge [jan]
- mov ax,xmax ;right of display on PC [jan]
- add ax,7 ;[jan]
- scale2: push ax
- mov ax,bx
- mul ymult ; scale y-coord
- mov si,ydiv ; get divisor
- shr si,1 ; halve it
- add ax,si ; add in - to round to nearest integer
- adc dx,0
- div ydiv
- mov bx,ybot
- sub bx,ax ; Put new Y in right reg
- jns scale3 ; ns = not too far
- mov bx,0
- scale3: pop ax ; Put new X in right reg
- mov scalex,ax ; save scaled values
- mov scaley,bx
- pop si
- pop dx
- ret
- SCALE ENDP
-
- ; LINE Subroutine to plot a line with endpoints in AX,BX and SI,DI.
- ; fast line drawing routine for the IBM PC
- ;
- ; Registers at CALL
- ; -----------------
- ; SI=Start X coord, all in PC coordinates
- ; DI=Start Y coord
- ; AX=End X coord
- ; BX=End Y coord
- ; CL=Color code: 1=draw foreground, 0=draw background, 0ffh=invert
- ; BP= line drawing pattern (is changed here by rotation)
- ; registers are all unchanged
-
- LINE PROC NEAR
- push ax
- push bx
- push cx
- push dx
- push si
- push di
- push es
- mov bp,linepat ; store active line pattern word in BP
- mov ccode,cl ; save color code in ccode for use by plot()
- ; first get coord to achieve increasing x; deltax >= 0
- sub ax,si ; deltax = x2 - x1
- jge line1 ; ge = going to the right, as desired
- neg ax ; make deltax non-negative
- sub si,ax ; swap the x coordinates
- xchg bx,di ; swap the y coordinates too
- ; second, compute deltay. ax = deltax, si = x1
- line1: sub bx,di ; deltay = y2 - y1
- call psetup ; setup display adapter for plotting
- ; and setup es:di to screen memory
- ; Choose algorithm based on |deltay| < |deltax| (use shallow) else steep.
- ; We arrange matters such that both deltas are non-negative.
- cmp bx,0 ; deltay
- jge line2 ; ge = non-negative
- neg linelen
- neg bx ; make non-negative
- line2: cmp bx,ax ; |deltay| versus |deltax|
- jbe shallow ; be = do shallow algorithm
- jmp steep ; else do steep algorithm
-
- ; shallow algorithm, move along x, di=y1, bx=deltay, si=x1, ax=deltax
- shallow:add bx,bx ; bx = 2*deltay
- mov cx,ax ; cx = number of steps (deltax here)
- inc cx ; loop dec's cx before testing
- mov dx,bx ; dx holds error
- sub dx,ax ; error = 2*deltay - deltax
- add ax,ax ; ax = 2*|deltax|
- shal1: call plotptr ; Plot(x,y)
- cmp dx,0
- jle shal2 ; le = error <= 0
- call pincy ; increment y by one scan line
- sub dx,ax ; error = error - 2*deltax
- shal2: add dx,bx ; error = error + 2*deltay
- inc si ; x = next dot right
- loop shal1
- shal3: jmp short plotex
-
- ; steep algorithm, move along y, di=y1, bx=deltay, si=x1, ax=deltax
- steep: add ax,ax ; ax = 2*deltax
- mov dx,ax ; dx holds error
- sub dx,bx ; error = 2*deltax(bx) - deltay (bx)
- mov cx,bx ; cx = number of steps (deltay here)
- inc cx ; loop dec's cx before testing
- add bx,bx ; bx = 2*|deltay|
- stee1: call plotptr ; Plot(x,y) x = ax, y = di
- cmp dx,0
- jle stee2 ; le error <= 0
- inc si ; x = next dot right
- sub dx,bx ; error = error - 2*deltay
- stee2: add dx,ax ; error = error + 2*deltax
- call pincy ; increment y
- loop stee1
- stee3:;;;jmp plotex
-
- plotex: mov ccode,1 ; reset to do foreground coloring
- pop es
- pop di
- pop si
- pop dx ; restore the world
- pop cx
- pop bx
- pop ax
- ret
- LINE ENDP
-
-
-
- ;;;;;;;; CGA plot support routines
- ; The CGA graphics memory mapping in mode 6 (640 by 200) is 8 dots per byte,
- ; left most dot in the high bit, 80 bytes per scan line, scan line segments
- ; alternating between 0b800h (even lines 0, 2, ...) and 0ba00h (odd lines).
- psetupc proc near ; CGA setup for plotting
- push ax
- push cx
- mov ax,linebytes
- mov linelen,ax ; 40 bytes per scan line
- mov cx,segscn ; small grid scn [jan]
- mov es,cx
- mov cx,di ; save copy of di, start y line
- ; compute starting point in regen buff
- mov ax,linebytes ; bytes per line [jan]
- mul di
- mov di,ax ; di = di * linebytes
- pop cx
- pop ax
- ret
- psetupc endp
-
- pincyc proc near ; CGA inc y
- add di,linelen ; add a line
- ret
- pincyc endp
-
- pltcga proc near ; CGA plot(x,y). x is in si, y is in di
- push bx ; used for HGA plot also.
- push si
- push di
- rol bp,1 ; rotate line pattern
- jnc pltcg3 ; nc = no bit to be plotted
- mov bx,si ; want si/8 for bytes along line
- shr si,1
- shr si,1
- shr si,1
- xor si,1 ;bytes in hl order on GRiD [jan]
- add di,si ; starting point in regen buffer
- and bx,0007h ; leave lower 3 bits for bit in byte
- ; di = offset in regen buffer
- mov bh,masktab[bx] ; 0-7 into bit mask in byte. x position
- mov bl,ccode ; get line type code
- cmp bl,1 ; draw the bit?
- jne pltcg1 ; ne = no
- or es:[di],bh ; drawn
- jmp short pltcg3
- pltcg1: cmp bl,0 ; draw in background (erase)?
- jne pltcg2 ; ne = no
- not bh
- and es:[di],bh ; erase the dots
- jmp short pltcg3
- pltcg2: xor es:[di],bh ; xor in this color
- pltcg3: pop di
- pop si
- pop bx
- ret
- pltcga endp
-
-
- ; GPUTC - a routine to send text characters from font to true graphics boards
- ; such as EGA, Hercules or CGA. Char is in al. Drawing routine ptr is gcplot.
-
- gputc proc near
-
- cmp al,' ' ; control character?
- jae gputc1 ; ae = no, display the char
- jmp putctrl ; else handle controls at putctrl
- gputc1: push ax ; first save some registers
- push bx
- push cx
- push es
- push di
- mov bl,al ; now BL has char to be displayed
- and bl,7fh ; no high bits allowed here
- ; set board mode
- mov di,y_coord ; get current y coord (char bottom)
- sub di,8 ; start 8 lines higher
- jnc gputc2 ; nc = ok
- mov di,0 ; move up to first line
- mov y_coord,8 ; and reset scan line indicator
- gputc2: call psetup ; enter with di=line number, sets es:di to
- ; start of line in display buf and
- ; sets byte-wide plot mode
- mov ax,x_coord ; compute regen buffer byte
- shr ax,1 ; want x_coord/8 for bytes along line
- shr ax,1
- shr ax,1
- xor ax,1 ;bytes in hl order on grid [jan]
- add di,ax ; byte in regen buffer
- xor bh,bh
- sub bx,32 ; characters in font start at 32
- shl bx,1
- shl bx,1 ; 8 bytes per char - hence * 8
- shl bx,1
- mov cx,8 ; 8 bytes (scan lines) to transfer
- call gcplot ; call character plot routine
- call incx ; move to next char position
- pop di
- pop es
- pop cx
- pop bx
- pop ax
- ret
- gputc endp
-
- putctrl proc near ; CONTROL CHARS = cursor movement
- push ax ; save character
- cmp al,FF ; formfeed?
- jne putct0 ; ne = no
- call TEKCLS ; FF clears the screen
- jmp putctx
- putct0: cmp al,BS ; BS? sends (logical) cursor back one
- jne putct2 ; ne = no, try next
- mov ax,x_coord
- sub ax,8 ; so delete 8 dots (move left)
- jns putct1 ; ns = non-negative
- mov ax,0 ; but not less than 0
- putct1: mov x_coord,ax ; and replace x coordinate
- mov al,' ' ; send a space
- call putc
- sub x_coord,8 ; restore cursor
- jmp putctx
- putct2: cmp al,tab ; tabs move forward one char position
- jne putct4 ; ne = not a tab
- call incx ; let incx move cursor right one col
- jmp putctx
- putct3: mov x_coord,ax
- jmp putctx
- putct4: cmp al,cr ; <CR> means go to beginning of line
- jne putct5
- mov x_coord,0 ; zero the x coordinate
- jmp putctx
- putct5: cmp al,lf ; <LF> means go down 8 pixels (1 line)
- jne putct7 ; ne = not LF
- add y_coord,8 ; border managed by outscrn and incx
- jmp putctx
- putct7: cmp al,vt ; <VT> move up screen 1 line (8 pixels)
- jne putctx
- sub y_coord,8 ; subtract one line (8 pixels)
- jnc putctx ; nc = space left
- mov y_coord,8 ; else set to top of screen
- putctx: pop ax
- ret
- putctrl endp
-
-
- incx proc near ; move the logical cursor right
- mov ax,x_coord ; shift the (logical) cursor right
- add ax,8 ; one character cell
- mov x_coord,ax
- cmp ax,xmax ; at end of the line?
- jbe incx1 ; b = no
- mov x_coord,0 ; wrap to next line
- add y_coord,8 ; next row
- mov ax,ybot ; last scan line
- cmp ax,y_coord ; below bottom line?
- jge incx1 ; ge = no
- mov y_coord,ax ; set to bottom row
- mov al,lf ; simulate a line feed operation
- call outscrn ; invoke More message
- incx1: ret
- incx endp
-
-
- ; General Character plot routine. Enter with bx pointing at font array for
- ; char, cx = number of bytes in char font, es:di = screen memory.
- ; Worker for gputc.
-
- gcgen proc near
- gcgen1: mov al,font[bx] ; Non-EGA systems: get bits from font
- cmp ccode,1 ; write in foreground?
- je gcgen2 ; e = yes
- xor es:[di],al ; background or xor (same)
- jmp short gcgen3
- ;;;; mov es:[di],al ; write desired pattern (no overwrite)
- gcgen2: OR es:[di],al ; write desired pattern (no overwrite)
- gcgen3: inc bx ; point to next byte of char pattern
- call pincy ; next scan line (linelen is preset)
- loop gcgen1 ; and repeat until complete
- ret
- gcgen endp
-
-
- teksave proc near ; saves graphics screen
- ; mimic procedure in msxgri.asm [jan]
- ret
- teksave endp
-
- tekrest proc near ; saves graphics screen of page 0 in page 1
- push si
- push di
- ; need to mimic the procedure in msxgri.asm for restoring a screen
- tekresx:pop di
- pop si
- ret
- tekrest endp
-
- code ends
- end
-
-